home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
comm
/
mail
/
Mutt089src.lha
/
Mutt-0.89i-AMIGA
/
src
/
rx
/
rxspencer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-01-28
|
27KB
|
1,192 lines
/* Copyright (C) 1995, 1996 Tom Lord
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this software; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <stdio.h>
#include "rxall.h"
#include "rxspencer.h"
#include "rxsimp.h"
static char * silly_hack_2 = 0;
struct rx_solutions rx_no_solutions;
#ifdef __STDC__
struct rx_solutions *
rx_make_solutions (struct rx_registers * regs, struct rx_unfaniverse * verse, struct rexp_node * expression, struct rexp_node ** subexps, int cset_size, int start, int end, rx_vmfn vmfn, rx_contextfn contextfn, void * closure)
#else
struct rx_solutions *
rx_make_solutions (regs, verse, expression, subexps, cset_size,
start, end, vmfn, contextfn, closure)
struct rx_registers * regs;
struct rx_unfaniverse * verse;
struct rexp_node * expression;
struct rexp_node ** subexps;
int cset_size;
int start;
int end;
rx_vmfn vmfn;
rx_contextfn contextfn;
void * closure;
#endif
{
struct rx_solutions * solns;
if ( expression
&& (expression->len >= 0)
&& (expression->len != (end - start)))
return &rx_no_solutions;
if (silly_hack_2)
{
solns = (struct rx_solutions *)silly_hack_2;
silly_hack_2 = 0;
}
else
solns = (struct rx_solutions *)malloc (sizeof (*solns));
if (!solns)
return 0;
rx_bzero ((char *)solns, sizeof (*solns));
solns->step = 0;
solns->cset_size = cset_size;
solns->subexps = subexps;
solns->exp = expression;
rx_save_rexp (expression);
solns->verse = verse;
solns->regs = regs;
solns->start = start;
solns->end = end;
solns->vmfn = vmfn;
solns->contextfn = contextfn;
solns->closure = closure;
if (!solns->exp || !solns->exp->observed)
{
solns->dfa = rx_unfa (verse, expression, cset_size);
if (!solns->dfa)
goto err_return;
rx_init_system (&solns->match_engine, solns->dfa->nfa);
if (rx_yes != rx_start_superstate (&solns->match_engine))
goto err_return;
}
else
{
struct rexp_node * simplified;
int status;
status = rx_simple_rexp (&simplified, cset_size, solns->exp, subexps);
if (status)
goto err_return;
solns->dfa = rx_unfa (verse, simplified, cset_size);
if (!solns->dfa)
{
rx_free_rexp (simplified);
goto err_return;
}
rx_init_system (&solns->match_engine, solns->dfa->nfa);
if (rx_yes != rx_start_superstate (&solns->match_engine))
goto err_return;
rx_free_rexp (simplified);
}
if (expression && ( (expression->type == r_concat)
|| (expression->type == r_plus)
|| (expression->type == r_star)
|| (expression->type == r_interval)))
{
struct rexp_node * subexp;
subexp = solns->exp->params.pair.left;
if (!subexp || !subexp->observed)
{
solns->left_dfa = rx_unfa (solns->verse, subexp, solns->cset_size);
}
else
{
struct rexp_node * simplified;
int status;
status = rx_simple_rexp (&simplified, solns->cset_size, subexp, solns->subexps);
if (status)
goto err_return;
solns->left_dfa = rx_unfa (solns->verse, simplified, solns->cset_size);
rx_free_rexp (simplified);
}
if (!solns->left_dfa)
goto err_return;
rx_bzero ((char *)&solns->left_match_engine, sizeof (solns->left_match_engine));
rx_init_system (&solns->left_match_engine, solns->left_dfa->nfa);
}
return solns;
err_return:
rx_free_rexp (solns->exp);
free (solns);
return 0;
}
#ifdef __STDC__
void
rx_free_solutions (struct rx_solutions * solns)
#else
void
rx_free_solutions (solns)
struct rx_solutions * solns;
#endif
{
if (!solns)
return;
if (solns == &rx_no_solutions)
return;
if (solns->left)
{
rx_free_solutions (solns->left);
solns->left = 0;
}
if (solns->right)
{
rx_free_solutions (solns->right);
solns->right = 0;
}
if (solns->dfa)
{
rx_free_unfa (solns->dfa);
solns->dfa = 0;
}
if (solns->left_dfa)
{
rx_terminate_system (&solns->left_match_engine);
rx_free_unfa (solns->left_dfa);
solns->left_dfa = 0;
}
rx_terminate_system (&solns->match_engine);
if (solns->exp)
{
rx_free_rexp (solns->exp);
solns->exp = 0;
}
if (!silly_hack_2)
silly_hack_2 = (char *)solns;
else
free (solns);
}
#ifdef __STDC__
static enum rx_answers
rx_solution_fit_p (struct rx_solutions * solns)
#else
static enum rx_answers
rx_solution_fit_p (solns)
struct rx_solutions * solns;
#endif
{
unsigned const char * burst;
int burst_addr;
int burst_len;
int burst_end_addr;
int rel_pos_in_burst;
enum rx_answers vmstat;
int current_pos;
current_pos = solns->start;
next_burst:
vmstat = solns->vmfn (solns->closure,
&burst, &burst_len, &burst_addr,
current_pos, solns->end,
current_pos);
if (vmstat != rx_yes)
return vmstat;
rel_pos_in_burst = current_pos - burst_addr;
burst_end_addr = burst_addr + burst_len;
if (burst_end_addr >= solns->end)
{
enum rx_answers fit_status;
fit_status = rx_fit_p (&solns->match_engine,
burst + rel_pos_in_burst,
solns->end - current_pos);
return fit_status;
}
else
{
enum rx_answers fit_status;
fit_status = rx_advance (&solns->match_engine,
burst + rel_pos_in_burst,
burst_len - rel_pos_in_burst);
if (fit_status != rx_yes)
{
return fit_status;
}
else
{
current_pos += burst_len - rel_pos_in_burst;
goto next_burst;
}
}
}
#ifdef __STDC__
static enum rx_answers
rx_solution_fit_str_p (struct rx_solutions * solns)
#else
static enum rx_answers
rx_solution_fit_str_p (solns)
struct rx_solutions * solns;
#endif
{
int current_pos;
unsigned const char * burst;
int burst_addr;
int burst_len;
int burst_end_addr;
int rel_pos_in_burst;
enum rx_answers vmstat;
int count;
unsigned char * key;
current_pos = solns->start;
count = solns->exp->params.cstr.len;
key = (unsigned char *)solns->exp->params.cstr.contents;
next_burst:
vmstat = solns->vmfn (solns->closure,
&burst, &burst_len, &burst_addr,
current_pos, solns->end,
current_pos);
if (vmstat != rx_yes)
return vmstat;
rel_pos_in_burst = current_pos - burst_addr;
burst_end_addr = burst_addr + burst_len;
{
unsigned const char * pos;
pos = burst + rel_pos_in_burst;
if (burst_end_addr >= solns->end)
{
while (count)
{
if (*pos != *key)
return rx_no;
++pos;
++key;
--count;
}
return rx_yes;
}
else
{
int part_count;
int part_count_init;
part_count_init = burst_len - rel_pos_in_burst;
part_count = part_count_init;
while (part_count)
{
if (*pos != *key)
return rx_no;
++pos;
++key;
--part_count;
}
count -= part_count_init;
current_pos += burst_len - rel_pos_in_burst;
goto next_burst;
}
}
}
#if 0
#ifdef __STDC__
int
rx_best_end_guess (struct rx_solutions * solns, struct rexp_node * exp, int bound)
#else
int
rx_best_end_guess (solns, exp, bound)
struct rx_solutions * solns;
struct rexp_node * exp;
int bound;
#endif
{
int current_pos;
unsigned const char * burst;
int burst_addr;
int burst_len;
int burst_end_addr;
int rel_pos_in_burst;
int best_guess;
enum rx_answers vmstat;
#if 0
unparse_print_rexp (256, solns->exp);
printf ("\n");
unparse_print_rexp (256, exp);
printf ("\nbound %d \n", bound);
#endif
if (rx_yes != rx_star